﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Reflection;

namespace AjaxEngines
{
    /// <summary>
    /// 数据转换者
    /// </summary>
    /// 
    [Serializable]
    public class DataConverter
    {
        private object _Data=null;
        private RenderContentTypes _ContentType = RenderContentTypes.text;

        #region 构造
        /// <summary>
        /// 构造一个数据转换者
        /// </summary>
        /// <param name="data">源数据</param>
        public DataConverter(object data)
        {
            _Data = data;
        }
        /// <summary>
        /// 构造一个数据转换者
        /// </summary>
        /// <param name="data">源数据</param>
        /// <param name="contentType">输入的数据类型</param>
        public DataConverter(object data,RenderContentTypes contentType)
        {
            _Data = data;
            _ContentType = contentType;
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// DataTable转为json字符串
        /// </summary>
        /// <returns>转换后数据字符串</returns>
        private string DataTableToJsonString(DataTable _DataTable)
        {
            StringBuilder jsonBuilder = new StringBuilder();
            //
            jsonBuilder.Append("{\"tablename\":\""+_DataTable.TableName+"\",\"rows\":[");
            //
            int RowCount = _DataTable.Rows.Count;
            for (int i = 0; i < RowCount; i++)
            {
                jsonBuilder.Append("{");
                int ColCount = _DataTable.Columns.Count;
                for (int j = 0; j < ColCount; j++)
                {
                    jsonBuilder.Append("\"");
                    jsonBuilder.Append(_DataTable.Columns[j].ColumnName);
                    jsonBuilder.Append("\":\"");
                    jsonBuilder.Append(_DataTable.Rows[i][j].ToString().Replace("\"", "\\\"").Replace("\r\n","\\r\\n"));
                    jsonBuilder.Append("\",");
                }
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
                jsonBuilder.Append("},");
            }
            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            //
            jsonBuilder.Append("]}");
            //
            return jsonBuilder.ToString();
        }
        /// <summary>
        /// DataSet转为Json字符串
        /// </summary>
        /// <param name="ds">DataSet</param>
        /// <returns>转换后数据字符串</returns>
        private string DataSetToJsonString(DataSet ds)
        {
            if (ds != null && ds.Tables[0] != null)
                return DataTableToJsonString(ds.Tables[0]);
            else
                return "";
        }
        /// <summary>
        /// 数据表的一行转为JsonString
        /// </summary>
        /// <param name="dr">DataRow</param>
        /// <returns>转换后数据字符串</returns>
        private string DataRowToJsonString(DataRow dr)
        {
            DataTable tempTable = dr.Table.Clone();
            tempTable.Rows.InsertAt(dr, 0);
            return DataTableToJsonString(tempTable);
        }
        /// <summary> 
        /// 简单对象转为Json字符串 
        /// </summary> 
        /// <param name="ins">object</param> 
        /// <returns>转换后数据字符串</returns> 
        private string ObjectToJsonScring(object ins)
        {
            Type a = ins.GetType();
            StringBuilder sb = new StringBuilder();
            sb.Append("{");
            MemberInfo[] mis = a.GetMembers();
            foreach (MemberInfo mi in mis)
            {
                object mival = GetMemberValue(ins, mi);
                if (mival != null)
                {
                    sb.Append("\"");
                    sb.Append(mi.Name);
                    sb.Append("\":\"");
                    string mivaltypename = mival.GetType().Name.ToUpper();
                    sb.Append(mival.ToString());
                    sb.Append("\",");
                }
            }
            sb.Remove(sb.Length - 1, 1);
            sb.Append("}");
            if (sb.Length > 2)
                return sb.ToString();
            else
                return "";
        }
        /// <summary> 
        /// 取一个字段或属性的值. 
        /// </summary> 
        /// <param name="ins">object</param> 
        /// <param name="member">成员</param> 
        /// <returns>值</returns> 
        private object GetMemberValue(object ins, MemberInfo member)
        {
            Type a = ins.GetType();
            try
            {
                return a.InvokeMember(member.Name, BindingFlags.GetProperty | BindingFlags.GetField, null, ins, null);
            }
            catch
            {
                return null;
            }
        } 
        /// <summary>
        /// 字符串转为Json字符串
        /// </summary>
        /// <param name="str">文本</param>
        /// <returns>转换后数据字符串</returns>
        private string StringToJsonString(string str)
        {
            str = "{\"string\":\""+str.Replace("\"", "\\\"").Replace("\r\n", "\\r\\n")+"\"}";
            return str;
        }
        #endregion

        /// <summary>
        /// 输出转换后数据字符串
        /// </summary>
        /// <returns>转换后数据字符串</returns>
        public override string ToString()
        {
            if (_Data == null)
                return null;
            string rs = "";
            Type type = _Data.GetType();
            string TypeName = type.Name.ToUpper();
            switch (TypeName)
            {
                case "DATATABLE":
                    rs = DataTableToJsonString((DataTable)_Data);
                    break;
                case "DATASET":
                    rs = DataSetToJsonString((DataSet)_Data);
                    break;
                case "STRING":
                    if (_ContentType == RenderContentTypes.json)
                        rs = StringToJsonString((string)_Data);
                    else 
                        rs = _Data.ToString();
                    break;
                case "DATAROW":
                    return DataRowToJsonString((DataRow)_Data);
                default:
                    rs = ObjectToJsonScring(_Data);
                    break;
            }
            return rs;
        }
        
    }
}